﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Context;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class UserService : BaseService, IUserService
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IMenuRepository _menuRepository;
        private readonly IUserRepository _userRepository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly IRoleMenuActionRepository _roleMenuActionRepository;
        public UserService(IMapper mapper, IUserRepository _userRepository, IUserRoleRepository userRoleRepository, IUnitOfWork _unitOfWork, IRoleMenuActionRepository _roleMenuActionRepository, IMenuRepository _menuRepository) : base(mapper)
        {
            this._roleMenuActionRepository = _roleMenuActionRepository;
            this._userRoleRepository = userRoleRepository;
            this._userRepository = _userRepository;
            this._menuRepository = _menuRepository;
            this._unitOfWork = _unitOfWork;
        }
        /// <summary>
        /// 16位MD5加密
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string MD5Encrypt16(string password)
        {
            var md5 = MD5.Create();
            string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(password)), 4, 8);
            t2 = t2.Replace("-", string.Empty);
            return t2;
        }
        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="m"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool AddUser(User m, out string message)
        {
            message = string.Empty;
            //判断该账号是否存在
            var uobj = _userRepository.QueryIsEntityWhere(x => x.UserName == m.UserName);
            if (uobj != null)
            {
                message = "该账号已存在！";
                return false;
            }
            m.Pwd = MD5Encrypt16(m.Pwd);
            //开启事务
            _unitOfWork.BeginTransaction();
            try
            {
                _userRepository.AddEntity(m);
                _unitOfWork.SaveChangesEntity();
                //循环遍历角色
                foreach (var item in m.RoleIds.Split(','))
                {
                    UserRole ur = new UserRole();
                    ur.Id = YitIdHelper.NextId();
                    ur.UserId = m.Id;
                    ur.RoleId = Convert.ToInt64(item);
                    _userRoleRepository.AddEntity(ur);
                }

                if (_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }

        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool DelUser(long uid)
        {
            var uobj = _userRepository.QueryEntityById(uid);
            if (uobj != null)
            {
                _userRepository.DelEntity(uobj);
                var urlist = _userRoleRepository.GetEntityAlls().Where(x => x.UserId == uid);
                if (urlist.Any())
                    _userRoleRepository.DelEntityList(urlist.ToList());
            }
            return _unitOfWork.SaveChangesEntity();
        }

        /// <summary>
        /// 判断登录
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public User GetLogin(LoginDto m, out string message)
        {
            message = string.Empty;
            var userobj = _userRepository.QueryIsEntityWhere(x => x.UserName == m.UserName);
            if (userobj == null)
            {
                message = "账号有误！";
                return null;
            }
            //MD5加密
            m.UserPassword = MD5Encrypt16(m.UserPassword);
            if (userobj.Pwd == m.UserPassword && userobj.Status == 1)
            {
                userobj.Pwd = string.Empty;
                return userobj;
            }
            message = "密码有误！";
            return null;
        }

        public List<UserRoleMenus> GetMenuitem(long uid)
        {
            var urlist = _userRoleRepository.GetEntityWhereAll(x => x.UserId == uid).Select(x => x.RoleId).Distinct().ToList();

            var rmalist = _roleMenuActionRepository.GetEntityAll().ToList();
          
            var mlist = _menuRepository.GetEntityAlls().ToList();

            var list = (from ur in urlist
                        join rma in rmalist
                        on ur equals rma.RoleId
                        group rma by rma.MenuId into g
                        select new UserRoleMenus
                        {
                            Id = g.Key,
                        }).ToList();
            List<UserRoleMenus> userRoleMenuslist = new List<UserRoleMenus>();
            int c = 0;
            foreach (var item in list)
            {
                var mobj = mlist.FirstOrDefault(x => x.Id == item.Id);
                if (mobj == null)
                    break;
                UserRoleMenus userRoleMenusobj = new UserRoleMenus();
                userRoleMenusobj.Id = mobj.Id;
                userRoleMenusobj.Title = mobj.MenuName;
                userRoleMenusobj.Icon = mobj.MenuIcon;
                userRoleMenusobj.Path = mobj.MenuUrl;
                userRoleMenusobj.ParentId = mobj.ParentId;
                userRoleMenusobj.AlwaysShow = mobj.IsHide;
                userRoleMenusobj.DisplayOrder = mobj.DisplayOrder;
                userRoleMenuslist.Add(userRoleMenusobj);
            }
            if (userRoleMenuslist.Any())
            {
                var lists = userRoleMenuslist.OrderBy(x => x.DisplayOrder);
                return GetMenuitemActions(lists.ToList(), 0);
            }

            return list;
        }

        public static List<UserRoleMenus> GetMenuitemActions(List<UserRoleMenus> list, long pid)
        {
            return list.Where(x => x.ParentId == pid).Select(x => new UserRoleMenus
            {
               Id= x.Id,
               Title= x.Title,
               Icon = x.Icon,
               ParentId = x.ParentId,
               Path = x.Path,
               AlwaysShow = x.AlwaysShow,
               Children = GetMenuitemActions(list,x.Id)
            }).ToList();
        }


        /// <summary>
        /// 根据用户Id获取对应权限
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<UserRoleMenuAction> GetMenuitemAction(long uid)
        {
            var urlist = _userRoleRepository.GetEntityWhereAll(x => x.UserId == uid).Select(x => x.RoleId).Distinct();

            var rmalist = _roleMenuActionRepository.GetEntityAll();

            var list = (from ur in urlist
                        join rma in rmalist
                        on ur equals rma.RoleId
                        group rma by rma.MenuId into g
                        select new UserRoleMenuAction
                        {
                            mid = g.Key,
                            aids = g.Select(x => x.ActionId).ToList()
                        }).ToList();

            return list;
        }

        /// <summary>
        /// 根据主键获取用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public User? GetUserById(long id)
        {
            var uobj = _userRepository.QueryEntityById(id);
            if (uobj != null)
            {
                //获取当前用户的所有角色
                var urlist = _userRoleRepository.GetEntityWhereAll(x => x.UserId == id);
                if (urlist.Any())
                {
                    foreach (var item in urlist)
                    {
                        uobj.RoleIds += item.RoleId + ",";
                    }
                    uobj.RoleIds = uobj.RoleIds.TrimEnd(',');
                    return uobj;
                }
                return uobj;
            }
            return null;
        }

        /// <summary>
        /// 用户显示
        /// </summary>
        /// <param name="uname"></param>
        /// <param name="rid"></param>
        /// <param name="state"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<User> GetUserList(string uname, long rid, int state, int pageIndex, int pageSize, out int totalCount)
        {
            var ulist = _userRepository.GetEntityAlls();
            if (!string.IsNullOrEmpty(uname))
            {
                ulist = ulist.Where(x => x.UserName.Contains(uname));
            }

            if (state != 3)
            {
                ulist = ulist.Where(x => x.Status == state);
            }

            ulist = _userRepository.GetEntityAlls(ulist, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return ulist.ToList();
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="m"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdUser(User m, out string message)
        {
            message = string.Empty;
            m.Pwd = MD5Encrypt16(m.Pwd);
            //开启事务
            _unitOfWork.BeginTransaction();
            _userRepository.UpdEntity(m);
            //获取当前用户的所有角色
            var urlist = _userRoleRepository.GetEntityWhereAll(x => x.UserId == m.Id);
            if (urlist.Any())
            {
                //删除当前用户的所有角色
                _userRoleRepository.DelEntityList(urlist.ToList());
            }
            //循环遍历角色
            foreach (var item in m.RoleIds.Split(','))
            {
                UserRole ur = new UserRole();
                ur.Id = YitIdHelper.NextId();
                ur.UserId = m.Id;
                ur.RoleId = Convert.ToInt32(item);
                _userRoleRepository.AddEntity(ur);
            }

            if (_unitOfWork.SaveChangesEntity())
                _unitOfWork.CommitChanges();
            return true;
        }
    }
}
